#!/usr/bin/ruby

#########################################
#        MFacl.rb                                                                              
#        description;                                                                          
#            provide acl control functions for MFd.rb                                          
#       version           1.10
#       last modified     06/23/06                                                            
#				Last Update				12/16/2010
#       Last change, modified error reporting levels, added output
#       allows as well as inputs for admin_allow
#########################################

ACL_VERSION=1.10

def set_kernopts
    retary=Array.new
    retary << "Activating Kernel Options\n"
    opts=Dir.new("/jail/acl/kernopts/")
    opts.each {|o|
				next if /\.svn$/ =~ o
        next if o !~ /[0-9a-zA-Z]/ and !o.include?"\.svn"

        t=MFreadlines("/jail/acl/kernopts/#{o}/path")
        if !t
            return "\tFAILED: kernopt #{o} key has no path\n"
        end
        target=t.shift    
        if active?("/jail/acl/kernopts/#{o}")
            v=MFreadlines("/jail/acl/kernopts/#{o}/value")
            if v
                value=v.shift

                if !system("echo #{value} > #{target}")
                    retary << "\tFAILED: activating kernopt #{o} (#{value})\n"
                end            
            else
                if !system("echo 1 > #{target}")
                    retary << "\tFAILED: activating kernopt #{o}\n"
                end
            end
        else
            if !system("echo 0 > #{target}")
                retary << "\tFAILED: de-activating kernopt #{o}\n"
            end 
        end
        }
        return retary.to_s
end

def get_rules(dir)
    rule_list=Array.new
    retary=Array.new
    i=Dir.new(dir)
    i.each {|x|
        next if x !~ /[0-9a-zA-Z]/
        rule_list << x
    }
    rule_list.sort{|y,x| y.to_f <=> x.to_f}.each { |line|
        rules=Array.new
        rules=MFreadlines("#{dir}/#{line}")
        if rules
            rules.each {|r|
                retary << r
            }
        end
        
    }
    return retary
end    

def add_TUrules (chain,rules,proto)
    retary=Array.new
    rules.each {|r|
        if !system("#{$iptables} -A #{chain} -p #{proto} --dport #{r} -j ACCEPT")
            retary << "\tFAILED: adding allow for #{proto} port #{r} to #{chain} with IPv4\n"
        end
        if !system("#{$ip6tables} -A #{chain} -p #{proto} --dport #{r} -j ACCEPT")
            retary << "\tFAILED: adding allow for #{proto} port #{r} to #{chain} with IPv6\n"
        end
    }
    return retary.to_s
end

def add_ICMPrules(chain,rules)
    retary=Array.new
    rules.each {|r|
        if !system("#{$iptables} -A #{chain} -p icmp --icmp-type #{r} -j ACCEPT")
            retary << "\tFAILED: adding allow for icmp type #{r} to #{chain} with IPv4\n"
        end
        if !system("#{$ip6tables} -A #{chain} -p ipv6-icmp --icmpv6-type #{r} -j ACCEPT")
            retary << "\tFAILED: adding allow for ipv6-icmp type #{r} to #{chain} with IPv6\n"
        end
    }
    return retary.to_s
end

def admin_allow(rules)
    retary=Array.new
    rules.each {|r|
		if ipv4(r)
       if !system("#{$iptables} -A INPUT -p tcp -s #{r} --dport 22 -j ACCEPT")
          retary << "\tFAILED: adding admin allow for #{r} to port #{22} in #{chain} with IPv4\n"
       end
       if !system("#{$iptables} -A OUTPUT -p tcp -d #{r} --sport 22 -j ACCEPT")
          retary << "\tFAILED: adding admin allow for #{r} to port #{22} in #{chain} with IPv4\n"
       end
		else
			if !system("#{$ip6tables} -A INPUT -p tcp -s #{r} --dport 22 -j ACCEPT")
      	retary << "\tFAILED: adding admin allow for #{r} to port #{22} in #{chain} with IPv6\n"
		   end
      if !system("#{$ip6tables} -A OUTPUT -p tcp -d #{r} --sport 22 -j ACCEPT")
         retary << "\tFAILED: adding admin allow for #{r} to port #{22} in #{chain} with IPv6\n"
       end
		end
    }
		
    return retary.to_s
end

def vpn_allow(chain,rules)
    retary=Array.new
    rules.each {|r|
        if !system("#{$iptables} -A #{chain} -p 50  -s #{r} -j ACCEPT")
            retary << "\tFAILED: adding vpn allow for #{r} to proto 50 in #{chain}\n"
        end
        if !system("#{$iptables} -A #{chain} -p udp --dport 500 -d #{r} -j ACCEPT")
            retary << "\tFAILED: adding vpn allow for #{r} to proto udp/500 dest in #{chain}\n"
        end
        if !system("#{$iptables} -A #{chain} -p udp --dport 500 -s #{r} -j ACCEPT")
            retary << "\tFAILED: adding vpn allow for #{r} to proto udp/500 src in #{chain}\n"
        end
    }
    return retary.to_s
end

def add_rules(chain,rules)
    retary=Array.new
    rules.each {|r|
        if chain.include?("in") && !r.include?("-o ")
            retary << "\tFAILED: adding rule #{r} to chain #{chain} (no output specifier (-o ALL is allowed))\n"
        elsif  chain.include?("in") && r.include?("-o ALL")
            # this rule should apply to all zones, strip out the -o stuff
            rtmp=r.gsub("-o ALL","")
					if !ipv6(r)	
            if !system("#{$iptables} -A #{chain} #{rtmp}")
                retary << "\tFailed: adding rule #{rtmp} to chain #{chain}\n"
            end
					end
					if !ipv4(r)	
            if !system("#{$ip6tables} -A #{chain} #{rtmp}")
                retary << "\tFailed: adding rule #{rtmp} to chain #{chain} with IPv6 #{__LINE__}\n"
            end
					end
        elsif  chain.include?("in") && r.include?("-o all")
            # this rule should apply to all zones, strip out the -o stuff
            rtmp=r.gsub("-o all","")
					if !ipv6(r)	
            if !system("#{$iptables} -A #{chain} #{rtmp}")
                retary << "\tFailed: adding rule #{rtmp} to chain #{chain}\n"
            end
					end
					if !ipv4(r)	
#						if !r.include?"icmp"
	            if !system("#{$ip6tables} -A #{chain} #{rtmp}")
                retary << "\tFailed: adding rule #{rtmp} to chain #{chain} with IPv6 #{__LINE__}\n"
#							end
            end
					end
        elsif chain.include?("in")
            # this rule has a specific output zone
					if !ipv6(r)	
            if !system("#{$iptables} -A #{chain} #{r}")
                retary << "\tFailed: adding rule #{r} to chain #{chain}\n"
            end
          end
					if !ipv4(r)	
            if !system("#{$ip6tables} -A #{chain} #{r}")
                retary << "\tFailed: adding rule #{r} to chain #{chain} with IPv6 #{__LINE__}\n"
            end
					end
				else 
					#If we have no v4 and no v6, it needs to be added twice
					if !ipv4(r) and !ipv6(r)
						r=r.gsub("ULOG --ulog-qthreshold 48 --ulog-nlgroup 1 --ulog-","LOG --log-")
						if !system("#{$iptables} -A #{chain} #{r}")
           	 retary << "\tFailed: adding rule #{r} to chain #{chain} ipv4 #{__LINE__} \n"
						end
						if !system("#{$ip6tables} -A #{chain} #{r}")
  	       		retary << "\tFailed: adding rule #{r} to chain #{chain} ipv6 #{__LINE__} \n"
						end
					end #It is not specific

					if ipv4(r) and !ipv6(r)
						if !system("#{$iptables} -A #{chain} #{r}")
           	 retary << "\tFailed: adding rule #{r} to chain #{chain} #{__LINE__} \n"
						end
					end
					if ipv6(r) and !ipv4(r)
#	if !r.include?"icmp"
#							r=r.gsub("ULOG --ulog-qthreshold 48 --ulog-nlgroup 1 --ulog-","LOG --log-")
#							if !system("#{$ip6tables} -A #{chain} #{r}")
# 	         	 retary << "\tFailed: adding rule #{r} to chain #{chain} #{__LINE__} \n"
#							end
#						elsif r.include?"icmpv6"
							r=r.gsub("ULOG --ulog-qthreshold 48 --ulog-nlgroup 1 --ulog-","LOG --log-")
							if !system("#{$ip6tables} -A #{chain} #{r}")
  	         	 retary << "\tFailed: adding rule #{r} to chain #{chain} #{__LINE__} \n"
							end
#						end
					end

        end
    }
    return retary
end

def add_bans(chain,rules)
    retary=Array.new
    rules.each {|r|
        if r.include?("-")
            t=r.split('-')
            t2=t[0].split('.')
            first=t2[3].to_i
            last=t[1].to_i
            base="#{t2[0]}.#{t2[1]}.#{t2[3]}."
            while first <= last
                h="#{base}#{first}"
                if !system("#{$iptables} -A #{chain} -s #{h} -j DROP")
                    retary << "\tFAILED: adding ban for src #{h} to #{chain}\n"
                end
                if !system("#{$iptables} -A #{chain} -d #{h} -j DROP")
                    retary << "\tFAILED: adding ban for dst #{h} to #{chain}\n"
                end
                first +=1
            end
        else
            if !system("#{$iptables} -A #{chain} -s #{r} -j DROP")
                retary << "\tFAILED: adding ban for src #{r} to #{chain}\n"
            end
            if !system("#{$iptables} -A #{chain} -d #{r} -j DROP")
                retary << "\tFAILED: adding ban for dst #{r} to #{chain}\n"
            end
        end
    }
    return retary.to_s
end
def acl_stopzone(zone)
    retary=Array.new
    if zone == "GLOBAL"
        if !system("#{$ip6tables} -F #{zone}")
            retary << "\tFAILED: acl command on #{zone} (#{$ip6tables} -F #{zone})\n"
          end                
        if !system("#{$iptables} -F #{zone}")
            retary << "\tFAILED: acl command on #{zone} (#{$iptables} -F #{zone})\n"
          end                
        return
    end
    if !test(?r, "/jail/acl/zones/#{zone}/interface")  
        return "\tFAILED: zone #{zone} is invalid\n"
    elsif !test(?r,"/jail/acl/zones/#{zone}/interface/int")
        return "\tFAILED: zone #{zone} interface is invalid\n"    
    elsif !test(?d, "/jail/acl/zones/#{zone}/in/rules")
        return "\tFAILED: zone #{zone} input rules is not a directory\n"
    elsif !test(?d, "/jail/acl/zones/#{zone}/out/rules")
        return "\tFAILED: zone #{zone} output rules is not a directory\n"
    else
        if active?("/jail/acl/zones/#{zone}")
            if zone != "WAN"              
                # drop the forward links          
                zint=MFreadlines("/jail/acl/zones/#{zone}/interface/int").shift
                if !system("#{$iptables} -D FOUT -o #{zint} -j #{zone}out")
                    retary << "\tFAILED: removing FIN links to #{zone}out\n"
                end
                if !system("#{$ip6tables} -D FOUT -o #{zint} -j #{zone}out")
                    retary << "\tFAILED: removing FIN links to #{zone}out with IPv6\n"
                end
                if !system("#{$iptables} -D FIN -i #{zint} -j #{zone}in")
                    retary << "\tFAILED: removing FOUT links to #{zone}in\n"
                end
                if !system("#{$ip6tables} -D FIN -i #{zint} -j #{zone}in")
                    retary << "\tFAILED: removing FOUT links to #{zone}in with IPv6\n"
                end
                # flush the tables
                if !system("#{$iptables} -F #{zone}in")
                    retary << "\tFAILED: acl command on #{zone} (#{$iptables} -F #{zone}in)\n"
                end
                if !system("#{$iptables} -F #{zone}out")
                    retary << "\tFAILED: acl command on #{zone} (#{$iptables} -F #{zone}out)\n"
                end                
                if !system("#{$ip6tables} -F #{zone}in")
                    retary << "\tFAILED: acl command on #{zone} (#{$iptables} -F #{zone}in) with IPv6\n"
                end
                if !system("#{$ip6tables} -F #{zone}out")
                    retary << "\tFAILED: acl command on #{zone} (#{$iptables} -F #{zone}out) with IPv6\n"
                end                
                # drop the tables
                if !system("#{$iptables} -X #{zone}in")
                    retary << "\tFAILED: acl command on #{zone} (#{$iptables} -X #{zone}in)\n"
                end
                if !system("#{$iptables} -X #{zone}out")
                    retary << "\tFAILED: acl command on #{zone} (#{$iptables} -X #{zone}out)\n"
                end
                if !system("#{$ip6tables} -X #{zone}in")
                    retary << "\tFAILED: acl command on #{zone} (#{$ip6tables} -X #{zone}in) with IPv6\n"
                end
                if !system("#{$ip6tables} -X #{zone}out")
                    retary << "\tFAILED: acl command on #{zone} (#{$ip6tables} -X #{zone}out) with IPv6\n"
                end
            else #Zone is WAN
                if !system("#{$iptables} -P INPUT ACCEPT")
                    retary << "\tFAILED: acl command on #{zone} (#{$iptables} -P ACCEPT)\n"
                end
                if !system("#{$iptables} -F INPUT")
                    retary << "\tFAILED: acl command on #{zone} (#{$iptables} -F INPUT)\n"
                end
                if !system("#{$iptables} -P OUTPUT ACCEPT")
                    retary << "\tFAILED: acl command on #{zone} (#{$iptables} -P OUTPUT)\n"
                end
                if !system("#{$iptables} -F OUTPUT")
                    retary << "\tFAILED: acl command on #{zone} (#{$iptables} -F OUTPUT)\n"
                end
                if !system("#{$ip6tables} -P INPUT ACCEPT")
                    retary << "\tFAILED: acl command on #{zone} (#{$ip6tables} -P ACCEPT)\n"
                end
                if !system("#{$ip6tables} -F INPUT")
                    retary << "\tFAILED: acl command on #{zone} (#{$ip6tables} -F INPUT)\n"
                end
                if !system("#{$ip6tables} -P OUTPUT ACCEPT")
                    retary << "\tFAILED: acl command on #{zone} (#{$ip6tables} -P OUTPUT)\n"
                end
                if !system("#{$ip6tables} -F OUTPUT")
                    retary << "\tFAILED: acl command on #{zone} (#{$ip6tables} -F OUTPUT)\n"
                end
            end
        else
            return "\tNOTICE: zone #{zone} is deactivated by config.. skipping\n"
        end
    end
    return retary.to_s
end


def acl_startzone(zone)
retary=Array.new
    if zone == "GLOBAL"
        if !active?("/jail/acl/zones/GLOBAL")
            return "\tNOTICE: zone GLOBAL is deactivated by config.. skipping\n"
        end
        if !test(?r, "/jail/acl/zones/GLOBAL/rules")
            return "\tFAILED: GLOBAL zone is invalid\n"
        end
        retary << add_rules("GLOBAL",get_rules("/jail/acl/zones/GLOBAL/rules"))
        banlist=MFreadlines("/jail/acl/zones/#{zone}/ban_list")
        if banlist
            retary << add_bans("GLOBAL", banlist)
        end
        return retary
    end
    if !test(?r, "/jail/acl/zones/#{zone}/interface")  
        return "\tFAILED: zone #{zone} is invalid\n"
    elsif !test(?r,"/jail/acl/zones/#{zone}/interface/int")
        return "\tFAILED: zone #{zone} interface is invalid\n"    
    else
        if active?("/jail/acl/zones/#{zone}")
					print "Zone Start: #{zone}\n"
            if zone != "WAN"
                banlist=MFreadlines("/jail/acl/zones/#{zone}/ban_list")
                inp=MFreadlines("/jail/acl/zones/#{zone}/in/policy").shift
                inr=get_rules("/jail/acl/zones/#{zone}/in/rules")
                outp=MFreadlines("/jail/acl/zones/#{zone}/out/policy").shift
                outr=get_rules("/jail/acl/zones/#{zone}/out/rules")
                zint=MFreadlines("/jail/acl/zones/#{zone}/interface/int").shift
                # this is a forward zone
                # first create the input and output tables
                if !system("#{$iptables} -N #{zone}in")
                    # this must be a mistake, and they asked for a restart.. try that instead
                    return acl_restart(zone)
                end
                if !system("#{$iptables} -N #{zone}out")
                    retary << "\tFAILED: creating acl chain #{zone}out\n"
                end               
                if !system("#{$ip6tables} -N #{zone}in")
										retary << "\tFAILED: creating acl chain #{zone}in with IPv6\n"
                end
                if !system("#{$ip6tables} -N #{zone}out")
                    retary << "\tFAILED: creating acl chain #{zone}out with IPv6\n"
                end               
                # set ban_list
                if banlist
                    retary << add_bans("#{zone}in", banlist)
                    retary << add_bans("#{zone}out", banlist)
                end              
                # add the rules for the tables
                retary << add_rules("#{zone}in", inr)
                retary << add_rules("#{zone}out", outr)
                # add the jump to the forward table   
                if !system("#{$iptables} -A FIN -i #{zint} -j #{zone}in")
                    retary << "\tFAILED: creating FIN chain link to #{zone}in\n"
                end
                if !system("#{$iptables} -A FOUT -o #{zint} -j #{zone}out")
                    retary << "\tFAILED: creating  FOUT chain link to #{zone}out\n"
                end                  
                if !system("#{$ip6tables} -A FIN -i #{zint} -j #{zone}in")
                    retary << "\tFAILED: creating FIN chain link to #{zone}in with IPv6\n"
                end
                if !system("#{$ip6tables} -A FOUT -o #{zint} -j #{zone}out")
                    retary << "\tFAILED: creating  FOUT chain link to #{zone}out with IPv6\n"
                end                  
                # set policy
                # allow traffic inside my own zone to talk with each other
                myI=MFreadlines("/jail/acl/zones/#{zone}/interface/int").shift
                if !system("#{$iptables} -A #{zone}in -o #{myI} -j ACCEPT")
                    retary << "\tFailed: adding rule #{r} to chain #{chain}\n"
                end                
                if !system("#{$ip6tables} -A #{zone}in -o #{myI} -j ACCEPT")
                    retary << "\tFailed: adding rule #{r} to chain #{chain} with IPv6\n"
                end                
                case inp
                    when /^DROP/i; 
                        if !system("#{$iptables} -A #{zone}in -j DROP")
                            retary << "\tFAILED: setting policy on #{zone} input\n"
                        end
                        if !system("#{$ip6tables} -A #{zone}in -j DROP")
                            retary << "\tFAILED: setting policy on #{zone} input with IPv6\n"
                        end
                        
                    when /^ACCEPT/i;
                        outI=MFreadlines("/jail/acl/zones/WAN/interface/int").shift
                        if !system("#{$iptables} -A #{zone}in -o #{outI} -j ACCEPT")
                            retary << "\tFAILED: setting policy on #{zone} input\n"
                        end                    
                        if !system("#{$ip6tables} -A #{zone}in -o #{outI} -j ACCEPT")
                            retary << "\tFAILED: setting policy on #{zone} input with IPv6\n"
                        end                    
                    when /^LOG[-_]DROP/i;
                        if !system("#{$iptables} -A #{zone}in -j ULOG --ulog-qthreshold 48 --ulog-nlgroup 1 --ulog-prefix \"MFv4_BLOCK_#{zone}in\"")
                            retary << "\tFAILED: adding logging on #{zone} input\n"
                        end
                        if !system("#{$iptables} -A #{zone}in -j DROP")
                            retary << "\tFAILED: setting policy on #{zone} input\n"
                        end
                        if !system("#{$ip6tables} -A #{zone}in -j LOG  --log-prefix \"MFv4_BLOCK_#{zone}in\"")
                            retary << "\tFAILED: adding logging on #{zone} input with IPv6\n"
                        end
                        if !system("#{$ip6tables} -A #{zone}in -j DROP")
                            retary << "\tFAILED: setting policy on #{zone} input with IPv6\n"
                        end
                    when /^LOG[-_]ACCEPT/i;
                        if !system("#{$iptables} -A #{zone}in -j ULOG --ulog-qthreshold 48 --ulog-nlgroup 1 --ulog-prefix \"MFv4_ALLOWED_#{zone}in\"")
                            retary << "\tFAILED: adding logging on #{zone} input\n"
                        end
                        if !system("#{$iptables} -A #{zone}in -j ACCEPT")
                            retary << "\tFAILED: setting policy on #{zone} input\n"
                        end
                        if !system("#{$ip6tables} -A #{zone}in -j LOG --log-prefix \"MFv4_ALLOWED_#{zone}in\"")
                            retary << "\tFAILED: adding logging on #{zone} input with IPv6\n"
                        end
                        if !system("#{$ip6tables} -A #{zone}in -j ACCEPT")
                            retary << "\tFAILED: setting policy on #{zone} input with IPv6\n"
                        end
                end
                case outp
                    when /^DROP/i; 
                        if !system("#{$iptables} -A #{zone}out -j DROP")
                            retary << "\tFAILED: setting policy on #{zone} input\n"
                        end
                        if !system("#{$ip6tables} -A #{zone}out -j DROP")
                            retary << "\tFAILED: setting policy on #{zone} input with IPv6\n"
                        end
                        
                    when /^ACCEPT/i;
                        if !system("#{$iptables} -A #{zone}out -j ACCEPT")
                            retary << "\tFAILED: setting policy on #{zone} input\n"
                        end                    
                        if !system("#{$ip6tables} -A #{zone}out -j ACCEPT")
                            retary << "\tFAILED: setting policy on #{zone} input with IPv6\n"
                        end                    
                    when /^LOG[-_]DROP/i;
                        if !system("#{$iptables} -A #{zone}out -j ULOG --ulog-qthreshold 48 --ulog-nlgroup 1 --ulog-prefix \"MFv4_BLOCK_#{zone}out\"")
                            retary << "\tFAILED: adding logging on #{zone} input\n"
                        end
                        if !system("#{$iptables} -A #{zone}out -j DROP")
                            retary << "\tFAILED: setting policy on #{zone} input\n"
                        end
                        if !system("#{$ip6tables} -A #{zone}out -j LOG --log-prefix \"MFv4_BLOCK_#{zone}out\"")
                            retary << "\tFAILED: adding logging on #{zone} input with IPv6\n"
                        end
                        if !system("#{$ip6tables} -A #{zone}out -j DROP")
                            retary << "\tFAILED: setting policy on #{zone} input with IPv6\n"
                        end
                    when /^LOG[-_]ACCEPT/i;
                        if !system("#{$iptables} -A #{zone}out -j ULOG --ulog-qthreshold 48 --ulog-nlgroup 1 --ulog-prefix \"MFv4_ALLOWED_#{zone}out\"")
                            retary << "\tFAILED: adding logging on #{zone} input\n"
                        end
                        if !system("#{$iptables} -A #{zone}out -j ACCEPT")
                            retary << "\tFAILED: setting policy on #{zone} input\n"
                        end 
                        if !system("#{$ip6tables} -A #{zone}out -j LOG --log-prefix \"MFv4_ALLOWED_#{zone}out\"")
                            retary << "\tFAILED: adding logging on #{zone} input with IPv6\n"
                        end
                        if !system("#{$ip6tables} -A #{zone}out -j ACCEPT")
                            retary << "\tFAILED: setting policy on #{zone} input with IPv6\n"
                        end 
                end               
            else
                # this is our public interface
                # set ban_list
                banlist=MFreadlines("/jail/acl/zones/#{zone}/ban_list")
                admin=MFreadlines("/jail/acl/zones/#{zone}/admin_allow")
                vpn=MFreadlines("/jail/acl/zones/#{zone}/vpn_allow")
                inp=MFreadlines("/jail/acl/zones/#{zone}/in/policy").shift
                ini=MFreadlines("/jail/acl/zones/#{zone}/in/icmp_allow")
                int=MFreadlines("/jail/acl/zones/#{zone}/in/tcp_allow")
                inu=MFreadlines("/jail/acl/zones/#{zone}/in/udp_allow")
                inr=get_rules("/jail/acl/zones/#{zone}/in/rules")
                outp=MFreadlines("/jail/acl/zones/#{zone}/out/policy").shift
                outi=MFreadlines("/jail/acl/zones/#{zone}/out/icmp_allow")
                outt=MFreadlines("/jail/acl/zones/#{zone}/out/tcp_allow")
                outu=MFreadlines("/jail/acl/zones/#{zone}/out/udp_allow")
                outr=get_rules("/jail/acl/zones/#{zone}/out/rules")
                if banlist
                    retary << add_bans("INPUT", banlist)
                    retary << add_bans("OUTPUT", banlist)
                end
                
                # add admin allow
                if admin
                    retary << admin_allow(admin)
                end
                # add vpn allow
                
                if vpn
                    retary << vpn_allow("INPUT", vpn)
                    retary << vpn_allow("OUTPUT", vpn)
                end
                
                # add tcp_allow
                if int
                    retary << add_TUrules("INPUT", int, "tcp")
                end
                if outt
                    retary << add_TUrules("OUTPUT", outt, "tcp")
                end
                
                # add udp_allow
                if inu
                    retary << add_TUrules("INPUT", inu, "udp")
                end
                if outu
                    retary << add_TUrules("OUTPUT", outu, "udp")
                end
                
                # add icmp_allow
                if ini
                    retary << add_ICMPrules("INPUT", ini)
                end
                if outi
                    retary << add_ICMPrules("OUTPUT", outi)
                end
                
                # create the rules
                retary << add_rules("INPUT", inr)
                retary << add_rules("OUTPUT", outr)
 
                # set policy
                case inp
                    when /^DROP/i; 
                        if !system("#{$iptables} -P INPUT DROP")
                            retary << "\tFAILED: setting policy on #{zone} input\n"
                        end
                        if !system("#{$ip6tables} -P INPUT DROP")
                            retary << "\tFAILED: setting policy on #{zone} input with IPv6\n"
                        end
                        
                    when /^ACCEPT/i;
                        if !system("#{$iptables} -P INPUT ACCEPT")
                            retary << "\tFAILED: setting policy on #{zone} input\n"
                        end                    
                        if !system("#{$ip6tables} -P INPUT ACCEPT")
                            retary << "\tFAILED: setting policy on #{zone} input with IPv6\n"
                        end                    
                    when /^LOG[-_]DROP/i;
                        if !system("#{$iptables} -P INPUT DROP")
                            retary << "\tFAILED: setting policy on #{zone} input\n"
                        end
                        if !system("#{$iptables} -A INPUT -j ULOG --ulog-qthreshold 48 --ulog-nlgroup 1 --ulog-prefix \"MFv4_BLOCK_#{zone}\"")
                            retary << "\tFAILED: adding logging on #{zone} input\n"
                        end
                        if !system("#{$ip6tables} -P INPUT DROP")
                            retary << "\tFAILED: setting policy on #{zone} input with IPv6\n"
                        end
                        if !system("#{$ip6tables} -A INPUT -j LOG  --log-prefix \"MFv4_BLOCK_#{zone}\"")
                            retary << "\tFAILED: adding logging on #{zone} input with IPv6\n"
                        end
                    when /^LOG[-_]ACCEPT/i;
                        if !system("#{$iptables} -P INPUT ACCEPT")
                            retary << "\tFAILED: setting policy on #{zone} input\n"
                        end
                        if !system("#{$iptables} -A INPUT -j ULOG --ulog-qthreshold 48 --ulog-nlgroup 1 --ulog-prefix \"MFv4_ALLOWED_#{zone}\"")
                            retary << "\tFAILED: adding logging on #{zone} input\n"
                        end
                        if !system("#{$ip6tables} -P INPUT ACCEPT")
                            retary << "\tFAILED: setting policy on #{zone} input with IPv6\n"
                        end
                        if !system("#{$ip6tables} -A INPUT -j LOG  --log-prefix \"MFv4_ALLOWED_#{zone}\"")
                            retary << "\tFAILED: adding logging on #{zone} input with IPv6\n"
                        end
                end
                case outp
                    when /^DROP/i; 
                        if !system("#{$iptables} -P OUTPUT DROP")
                            retary << "\tFAILED: setting policy on #{zone} output\n"
                        end
                        if !system("#{$ip6tables} -P OUTPUT DROP")
                            retary << "\tFAILED: setting policy on #{zone} output with IPv6\n"
                        end
                        
                    when /^ACCEPT/i;
                        if !system("#{$iptables} -P OUTPUT ACCEPT")
                            retary << "\tFAILED: setting policy on #{zone} output\n"
                        end                    
                        if !system("#{$ip6tables} -P OUTPUT ACCEPT")
                            retary << "\tFAILED: setting policy on #{zone} output with IPv6\n"
                        end                    
                    when /^LOG[-_]DROP/i;
                        if !system("#{$iptables} -P OUTPUT DROP")
                            retary << "\tFAILED: setting policy on #{zone} output\n"
                        end
                        if !system("#{$iptables} -A OUTPUT -j ULOG --ulog-qthreshold 48 --ulog-nlgroup 1 --ulog-prefix \"MFv4_BLOCK_#{zone}\"")
                            retary << "\tFAILED: adding logging on #{zone} output\n"
                        end
                        if !system("#{$ip6tables} -P OUTPUT DROP")
                            retary << "\tFAILED: setting policy on #{zone} output with IPv6\n"
                        end
                        if !system("#{$ip6tables} -A OUTPUT -j LOG --log-prefix \"MFv4_BLOCK_#{zone}\"")
                            retary << "\tFAILED: adding logging on #{zone} output with IPv6\n"
                        end
                    when /^LOG[-_]ACCEPT/i;
                        if !system("#{$iptables} -P OUTPUT ACCEPT")
                            retary << "\tFAILED: setting policy on #{zone} output\n"
                        end
                        if !system("#{$iptables} -A OUTPUT -j ULOG --ulog-qthreshold 48 --ulog-nlgroup 1 --ulog-prefix \"MFv4_ALLOWED_#{zone}\"")
                            retary << "\tFAILED: adding logging on #{zone} output\n"
                        end
                        if !system("#{$ip6tables} -P OUTPUT ACCEPT")
                            retary << "\tFAILED: setting policy on #{zone} output with IPv6\n"
                        end
                        if !system("#{$ip6tables} -A OUTPUT -j LOG  --log-prefix \"MFv4_ALLOWED_#{zone}\"")
                            retary << "\tFAILED: adding logging on #{zone} output with IPv6\n"
                        end
                end               
            end
        else
            return "\tNOTICE: zone #{zone} is deactivated by config.. skipping\n"
        end
    end
    return retary.to_s

end

def acl_allstart
    retary=Array.new
    retary << set_kernopts
    # create the global table
    if !system("#{$iptables} -N GLOBAL")
        retary << "\tFAILED: error creating GLOBAL table\n"
    end
    if !system("#{$iptables} -N FIN")
        retary << "\tFAILED: error creating FIN table\n"
    end
    if !system("#{$iptables} -N FOUT")
        retary << "\tFAILED: error creating FOUT table\n"
    end
    if !system("#{$ip6tables} -N GLOBAL")
        retary << "\tFAILED: error creating GLOBAL table\n"
    end
    if !system("#{$ip6tables} -N FIN")
        retary << "\tFAILED: error creating FIN table with IPv6\n"
    end
    if !system("#{$ip6tables} -N FOUT")
        retary << "\tFAILED: error creating FOUT table with IPv6\n"
    end
    # link FORWARD, INPUT and OUTPUT tables to GLOBAL
    if !system("#{$iptables} -A INPUT -j GLOBAL")
        retary << "\tFAILED: setting GLOBAL jump on INPUT table\n"
    end
    if !system("#{$iptables} -A OUTPUT -j GLOBAL")
        retary << "\tFAILED: setting GLOBAL jump on OUTPUT table\n"
    end
    if !system("#{$iptables} -A FORWARD -j GLOBAL")
        retary << "\tFAILED: setting GLOBAL jump on FORWARD table\n"
    end
    if !system("#{$iptables} -A FORWARD -j FIN")
        retary << "\tFAILED: setting FIN jump on FORWARD table\n"
    end
		if !system("#{$iptables} -A FORWARD -j FOUT")
        retary << "\tFAILED: setting FOUT jump on FORWARD table\n"
    end    
    if !system("#{$ip6tables} -A INPUT -j GLOBAL")
        retary << "\tFAILED: setting GLOBAL jump on INPUT table with IPv6\n"
    end
    if !system("#{$ip6tables} -A OUTPUT -j GLOBAL")
        retary << "\tFAILED: setting GLOBAL jump on OUTPUT table with IPv6\n"
    end
    if !system("#{$ip6tables} -A FORWARD -j GLOBAL")
        retary << "\tFAILED: setting GLOBAL jump on FORWARD table with IPv6\n"
    end
    if !system("#{$ip6tables} -A FORWARD -j FIN")
        retary << "\tFAILED: setting FIN jump on FORWARD table with IPv6\n"
    end
		if !system("#{$ip6tables} -A FORWARD -j FOUT")
        retary << "\tFAILED: setting FOUT jump on FORWARD table with IPv6\n"
    end    
    # cycle through zones activating all
    zones=Dir.new("/jail/acl/zones")
        zones.each {|z|    
            next if z !~ /[0-9a-zA-Z]/
						next if z =~ /\.svn/
            retary << "Activating acl for zone #{z}\n"
            retary << acl_start(z)
        }
    return retary.to_s
end

def acl_allstop
    retary=Array.new
    #cmds=["-P INPUT ACCEPT", "-P FORWARD ACCEPT", "-F", "-X", "-t mangle -F"]
    cmds=["-P INPUT ACCEPT", "-P FORWARD ACCEPT", "-P OUTPUT ACCEPT", "-F", "-X"]
    cmds.each {|cmd|
        tmp=system("#{$iptables} #{cmd}")
        if !tmp
            retary << "\tFAILED: acl comand #{cmd} returned error\n"
        end
        tmp=system("#{$ip6tables} #{cmd}")
        if !tmp
            retary << "\tFAILED: acl comand #{cmd} returned error with IPv6\n"
        end
        
    }
    return retary.to_s
end

def acl_stop(zone="all")
    if zone == "all"
        tmp=acl_allstop 
    else
        tmp=acl_stopzone(zone)
    end
    return tmp.to_s
end

def acl_start(zone="all")
    if zone == "all"
        tmp=acl_allstart
    else
        tmp=acl_startzone(zone)
    end
    return tmp.to_s
end

def acl_restart(zone="all")
    acl_stop(zone)
    acl_start(zone)
end

def acl_ver
    return "\tACL library version: #{ACL_VERSION}\n"
end

